// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

part of dart.core;

/**
 * 所有Dart对象的基类。
 *
 * 因为Object是Dart类层次结构的root，所有其他的Dart类都是Object的子类。
 *
 * 当你定义一个类，你应该通过重写[toString]，返回一个字符串描述那个类的实例。
 * 你可能也需要定义[hashCode]和[==]操作符，这在
 * [library tour](http://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html)的
 * [Implementing map keys](https://www.dartlang.org/docs/dart-up-and-running/ch03.html#implementing-map-keys)
 * 章节中有描述。
 */
class Object {
  /**
   * 创建一个新的[Object]实例。
   *
   * [Object]实例不存在有意义的状态，并且仅在通过其标记的时候有用。
   * 一个[Object]实例仅与它自身相等。
   */
  const Object();

  /**
   * 相等操作符。
   *
   * 默认情况下，所有的[Object]返回true，当且仅当[:this:]和[other]是同一对象的时候。
   *
   * 通过重写该函数来指定类的不同的相等关系。重写的方法必须保持一个相等的关系。
   * 也就是说，它必须：
   *
   *  * 总体：对于所有参数，它必须返回一个布尔值。它不应throw或return `null`。
   *
   *  * 自反性：对于所有对象`o`，`o == o`必须为true。
   *
   *  * 对称性：对于所有对象`o1`和`o2`，`o1 == o2`和`o2 == o1`必须都为true，或都为false。
   *
   *  * 传递性: 对于所有对象`o1`，`o2`和`o3`，如果`o1 == o2`和
   *    `o2 == o3`是true，那么`o1 == o3`必须是true。
   *
   * 随时间推移，该方法也必须是一致的。
   * 如果两个对象相等，结果不应该随时间而变化。
   * 或至少其中一个对象被修改才会改变。
   *
   * 如果子类重写相等操作符，它也应该重写[hashCode]方法，以保持一致。
   */
  bool operator ==(other) => identical(this, other);

  /**
   * 获取对象的哈希值。
   *
   * 所有的对象都有哈希值。哈希值能确保对象相同，
   * 当使用[:==:]操作符比较时，结果相等。
   * 除了在运行期间不一致，不能确定哈希值。
   *
   *     这两句感觉有歧义，原文如下，如果翻译不对请指正：
   *
   *     Other than that there are no guarantees about the hash codes.
   *     They will not be consistent between runs and there are no distribution guarantees.
   *
   * 如果子类重写[hashCode]，它也应该重写相等操作符，以保持一致。
   */
  external int get hashCode;

  /**
   * 返回一个用来表示对象的字符串。
   */
  external String toString();

  /**
   * 当一个不存在的函数或成员变量被访问时，该函数被调用。
   *
   * 类可以重写[noSuchMethod]来提供自定义行为。
   *
   * 如果返回一个值，那么这个值将成为原始调用的结果。
   *
   * 默认的行为是抛出一个[NoSuchMethodError]。
   */
  external dynamic noSuchMethod(Invocation invocation);

  /**
   * 对象的运行时类型的表示。
   */
  external Type get runtimeType;
}
